
var base_query_url = '',
    csacr_base_query_uri = '/google-dsapi-svc/addama/datasources/csacr',
    tcga_base_query_uri = '/google-dsapi-svc/addama/datasources/tcga',
    dataset_table = '/regulome_explorer_dataset/query';

var query_uri = '/query',
    parsed_data = {network : null,unlocated : null,features : null,unlocated_features:null,located_features:null},
    responses = {network : null},
    patients = {data : null},
    cancer = {sv : null},
    dataset_labels,
    current_data = '';
    network_query ='',
    network_uri = '',
    feature_uri ='',
    clin_uri ='',
    patient_uri =  '',
            pathway_uri = '',
    feature_data_uri =  '';

function registerDataRetrievalListeners() {
    var d = vq.events.Dispatcher;
    d.addListener('dataset_selected',function(obj){
        selectDataset(obj);
        loadDatasetLabels();
    });

    d.addListener('data_request','associations',function(obj){
        loadNetworkData(obj);
    });

    d.addListener('data_request','annotations', function(obj){
        loadAnnotations();
    });
    d.addListener('click_association',function(link) {
        loadFeatureData(link);
    });
}

 function selectDataset(set_label) {
    current_data = set_label;
    network_uri = '/mv_'+set_label+'_feature_networks/query';
    feature_uri = '/v_'+set_label+'_feature_sources/query';
    clin_uri = '/v_'+set_label+'_feature_clinlabel/query';
    patient_uri =  '/v_'+set_label+'_patients/query';
    feature_data_uri =  '/v_' + set_label + '_patient_values/query';
    pathway_uri = '/' + set_label + '_feature_pathways/query';
}

function loadDatasetLabels() {

     function loadComplete() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_complete','dataset_labels',dataset_labels));
    }

    function loadFailed() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','dataset_labels',{msg:'Retrieval Timeout'}));
    }

    var dataset_labels = {feature_sources : null, clin_labels : null, patients: null};

    var timer = new vq.utils.SyncDatasources(200,40,loadComplete,dataset_labels,loadFailed);
    timer.start_poll();
    var clin_label_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + clin_uri);
    clin_label_query.setQuery('select `label`');
    function clinicalLabelQueryHandler(response) {
     if (!response.isError()) {
        dataset_labels['clin_labels'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
         }
        else {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','dataset_labels',{msg:'Query Error: ' + response.getMessage() + ' ' + response.getDetailedMessage()}));
        }
        return;
    }
    clin_label_query.send(clinicalLabelQueryHandler);

    var sources_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + feature_uri);
    sources_query.setQuery('select source');

    function featureSourceQueryHandler(response) {
          if (!response.isError()) {
              dataset_labels['feature_sources'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
          }
          else {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','dataset_labels',{msg:'Query Error: ' + response.getMessage() + ' ' + response.getDetailedMessage()}));
        }
        return;
    }
    sources_query.send(featureSourceQueryHandler);

      var patient_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + patient_uri);
    patient_query.setQuery('limit 1');

    function patientQueryHandle(response) {
          if (!response.isError()) {
              dataset_labels['patients'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable())[0]['barcode'].split(':');
          }
          else {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','dataset_labels',{msg:'Query Error: ' + response.getMessage() + ' ' + response.getDetailedMessage()}));
        }
        return;
    }
    patient_query.send(patientQueryHandle);

}

function loadFeatureData(link) {

    function loadComplete() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_complete','features',patients));
    }

    function loadFailed() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','features',{msg:'Retrieval Timeout'}));
    }

    var patients = {data : null};
    var timer =  new vq.utils.SyncDatasources(200,40,loadComplete,patients,loadFailed);
    timer.start_poll();

    var query_str = 'select f1id, f2id, f1alias, f1values, f2alias, f2values ' +
            'where f1id  = ' + link.sourceNode.id + ' and f2id = ' + link.targetNode.id + ' limit 1';
    var patient_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + feature_data_uri);
    patient_query.setQuery(query_str);

    function patientQueryHandle(response) {
        if (!response.isError()) {
            patients['data'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
        }     else {
            vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','features',{msg:'Query Error: ' + response.getMessage() + ' ' + response.getDetailedMessage()}));
        }
        return;
    }
    patient_query.send(patientQueryHandle);

}

function loadAnnotations() {

    function loadComplete() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_complete','annotations',annotations));
    }

    function loadFailed() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','annotations',{msg:'Retrieval Timeout'}));
    }
    var annotations = {'chrom_leng': null};

    var timer = new vq.utils.SyncDatasources(200,40,loadComplete,annotations,loadFailed);
    timer.start_poll();
    var chrom_query = new google.visualization.Query(base_query_url + csacr_base_query_uri + '/chrom_info' + query_uri);
    chrom_query.setQuery('select chr_name, chr_length');
    function handleChromInfoQuery(response) {
        if (!response.isError()) {
            annotations['chrom_leng'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
        }
        else {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','annotations',{msg:'Query Error: ' + response.getMessage() + ' ' + response.getDetailedMessage()}));
        }
        return;
    }
    chrom_query.send(handleChromInfoQuery);
    return;
}

//function retrieveDatasetList(callback) {
//    dataset_lists = {tables : null};
//
//    var timer = new vq.utils.SyncDatasources(200,40,callback,dataset_labels);
//    timer.start_poll();
//    var table_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + dataset_table);
//    table_query.setQuery('select *');
//    function datasetTableQueryHandler(response) {
//        dataset_lists['tables'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
//    }
//    table_query.send(datasetTableQueryHandler);
//}


/*
not very good yet.  move json_array responsibility to server.. stop running cascading timers!
 */

function loadNetworkData(query_params,callback) {
    function loadComplete() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_complete','associations', responses));
    }

    function loadFailed() {
        vq.events.Dispatcher.dispatch(new vq.events.Event('query_fail','associations',{msg:'Retrieval Timeout'}));
    }

    var responses = {network : null};
    var response_check={data : null};
    var network_query=buildGQLQuery(query_params);

    function handleNetworkQuery(response) {
        response_check['data'] = 1;
        var timer = new vq.utils.SyncDatasources(400,40,loadComplete,responses,loadFailed);
        timer.start_poll();
        responses['network'] = vq.utils.GoogleDSUtils.dataTableToArray(response.getDataTable());
    }

    var association_query = new google.visualization.Query(base_query_url + tcga_base_query_uri + network_uri);
    association_query.setQuery(network_query);
    var timer = new vq.utils.SyncDatasources(100,40,function() {return null;},response_check, loadFailed);
    timer.start_poll();
    association_query.send(handleNetworkQuery);
}

/*
Utility functions
 */


function buildGQLQuery(args) {
      var query = 'select alias1, alias2, feature1id, feature2id, f1genescore, f2genescore, correlation, pvalue, importance';
    var whst = ' where',
    where = whst;

    if (args['f1_type'] != '' && args['f1_type'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f1source = \'' +args['f1_type']+ '\'';
    }
    if (args['f2_type'] != '' && args['f2_type'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f2source = \'' +args['f2_type']+ '\'';
    }
    if (args['f1_label'] != '' && args['f1_label'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += '`f1label` ' + parseLabel(args['f1_label']);
    }
     if (args['f2_label'] != '' && args['f2_label'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += '`f2label` ' + parseLabel(args['f2_label']);
    }
    if (args['f1_chr'] != '' && args['f1_chr'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f1chr = \'' +args['f1_chr']+'\'';
    }
    if (args['f2_chr'] != '' && args['f2_chr'] != '*') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f2chr = \'' +args['f2_chr']+'\'';
    }
    if (args['f1_start'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f1start >= ' +args['f1_start'];
    }
    if (args['f2_start'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f2start >= ' +args['f2_start'];
    }
    if (args['f1_stop'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f1end <= ' +args['f1_stop'];
    }
    if (args['f2_stop'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'f2end <= ' +args['f2_stop'];
    }
    if ((args['f2_start'] != '') && (args['f2_stop'] != '')) {
           where += ' and f2end >= ' +args['f2_start'];
           }
    if ((args['f1_start'] != '') && (args['f1_stop'] != '')) {
           where += ' and f1end >= ' +args['f1_start'];
           }
    if (args['importance'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'importance >= ' +args['importance'];
    }
    if (args['pvalue'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        where += 'pvalue <= ' +args['pvalue'];
    }
     if (args['correlation'] != '') {
        where += (where.length > whst.length ? ' and ' : ' ');
        var corr_fn = args['correlation_fn'];
    if (corr_fn == 'Btw'){
        where += '(correlation >= -' +args['correlation'] + ' and correlation <= ' + args['correlation'] +')';
    }else if (corr_fn == '<='){
        where += '(correlation <= ' + args['correlation'] +')';
    }else if (corr_fn == '>='){
        where += '(correlation >= ' +args['correlation'] +')';
    }else{
            where += '(correlation >= ' +args['correlation'] + ' or correlation <= -' + args['correlation'] +')';
    }
   }

    query += (where.length > whst.length ? where : '');
    query += ' order by '+args['order'] + (args['order'] == 'pvalue' ? ' ASC' : ' DESC');
    query += ' limit '+args['limit'] + ' label `feature1id` \'f1id\', `feature2id` \'f2id\'';

    return query;
}

function parseLabel(label) {
    if (label.length > 1 && label.indexOf('*') >= 0) {
        return 'like \'' + label.replace(new RegExp('[*]', 'g'),'%') + '\'';
         } else {
             return '=\'' + label + '\'';
    }
}

/*
Misc data/file retrieval
 */

    function downloadNetworkData(target_frame,output) {
        var output_label = output;
        var output_extension=output;
        if (output_label =='tsv') {output_extension=output_label;output_label='tsv-excel';}
        target_frame.src = 'http://' + window.location.host + encodeURI(base_query_url +
                tcga_base_query_uri + network_uri+ '?tq=' + network_query + '&tqx=out:' +output_label+';outFileName:'+current_data+'_query.'+output_extension);
    }


